﻿using EasyNetQ;

namespace RabbitMqExtend
{


    //https://www.cnblogs.com/shanfeng1000/p/12359190.html
    /// <summary>
    /// Queue 队列名 ExchangeName 交换机名称
    /// </summary>
    [Queue("my_queue_name", ExchangeName = "my_exchange_name")]
    public class TextMessage
    {
        public string Text { get; set; }
    }

    public class RabbitMqHelp
    {
        //关闭连接字需要调用Dispose方法即可，所以，在使用IBus时，切记不要无脑的使用using
        private IBus _bus;

        private ISubscriptionResult subscriptionResult;
        /// <summary>
        ///       
        /// </summary>
        /// <param name="connectionString">
        /// var connectionString = "host=192.168.18.129;virtualHost=/;username=admin;password=123456;timeout=60";
        ///         virtualhost 默认虚拟主机是’/’
        ///      username 默认是'guest'
        ///    password 默认为'guest'
        ///      requestedHearbeat 默认为10秒钟。没有心跳设置为0
        ///     prefetchcount 默认为50.这个值是在EasyNetQ发送ack之前发送给RabbitMQ的消息数。不限制设置为0（不推荐）. 为了在消费者之间保持公平和平衡设置为1.
        ///     persistentMessages 默认为true。这个决定了在发送消息时采用什么样的delivery_mode。设置为true，RabbitMQ将会把消息持久化到磁盘，并且在服务器重启后仍会存在。设置为false可以提高性能收益。
        ///    timeout 模式值为10秒。不限制超时时间设置为0.当超时事时抛出System.TimeoutException.
        ///    关闭连接字需要调用Dispose方法即可，所以，在使用IBus时，切记不要无脑的使用using
        /// </param>
        public RabbitMqHelp(string connectionString)
        {



            _bus = RabbitHutch.CreateBus(connectionString);
        }

        public IBus GetBus(string connectionString)
        {
            return _bus;
        }
        /// <summary>
        /// 发布消息
        /// </summary>
        /// <param name="t"></param>
        /// <param name="isAsync">是否异步</param>
        public void PublicMessage(TextMessage t, bool isAsync = false)
        {
            if (isAsync)
            {
                _bus.PublishAsync(t);
            }
            else
            {
                _bus.Publish(t);
            }
        }

        /// <summary>
        /// 处理消息的方法
        /// </summary>
        /// <param name="message"></param>
        public delegate void DoMessage(string message);

        /// <summary>
        /// 订阅消息
       // 因为Subscribe方法的subscriptionId参数，在未明确指定队列的情况下，如果使用同一个subscriptionId参数，则表示从同一个队列消费，因此可以使用subscriptionId来区分队列。
        /// </summary>
        /// <param name="subscriptionId">队列名</param>
        public ISubscriptionResult Subscribe(string subscriptionId, DoMessage f )
        {
              subscriptionResult=  _bus.Subscribe<TextMessage>(subscriptionId, tm =>
            {
                f(tm.Text);
            });
            return subscriptionResult;


        }
        ///// <summary>
        ///// 取消该消费的订阅  
        ///// 调用Dispose方法将停止EasyNetQ对队列的消费，并且关闭这个消费者的channel。
        ///// </summary>
        public void ConsumerCancellation()
        {
            subscriptionResult.ConsumerCancellation.Dispose();
        }
        /// <summary>
        /// 取消所有的订阅  注意：IBus和IAndvancedBus的dispose，能够取消所有消费者，并关闭对RabbitMQ的连接。
        /// </summary>
        public void ConsumerCancellationALL()
        {
            _bus.Dispose();
        }

    }
}